package com.mathlearning.auth.service;

import com.mathlearning.auth.common.BusinessException;
import com.mathlearning.auth.dto.discussion.*;
import com.mathlearning.auth.entity.*;
import com.mathlearning.auth.repository.*;
import com.mathlearning.auth.specification.DiscussionSpecification;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class DiscussionService {

    @Autowired
    private DiscussionRepository discussionRepository;

    @Autowired
    private DiscussionTagRepository tagRepository;

    @Autowired
    private DiscussionLikeRepository likeRepository;

    @Autowired
    private DiscussionFavoriteRepository favoriteRepository;

    @Autowired
    private UserRepository userRepository;

    @Autowired
    private DiscussionCacheService cacheService;

    /**
     * 获取讨论列表（支持搜索、标签、排序的组合查询）
     */
    public DiscussionListResponse getDiscussionList(DiscussionListRequest request, Long currentUserId) {
        // 1. 构建查询条件
        Specification<Discussion> spec = Specification.where(DiscussionSpecification.isNotDeleted());
        
        // 添加关键词搜索条件
        if (request.getKeyword() != null && !request.getKeyword().trim().isEmpty()) {
            spec = spec.and(DiscussionSpecification.keywordLike(request.getKeyword()));
        }
        
        // 添加标签筛选条件
        if (request.getTag() != null && !request.getTag().trim().isEmpty()) {
            spec = spec.and(DiscussionSpecification.hasTag(request.getTag()));
        }
        
        // 2. 构建排序规则
        Sort sort = buildSort(request.getSort());
        
        // 3. 创建分页对象
        Pageable pageable = PageRequest.of(request.getPage() - 1, request.getPageSize(), sort);
        
        // 4. 执行查询
        Page<Discussion> page = discussionRepository.findAll(spec, pageable);

        // 5. 转换为DTO
        List<DiscussionResponse> list = page.getContent().stream()
                .map(d -> toDiscussionResponse(d, currentUserId))
                .collect(Collectors.toList());

        return new DiscussionListResponse(list, page.getTotalElements(), request.getPage(), request.getPageSize());
    }
    
    /**
     * 构建排序规则
     */
    private Sort buildSort(String sortType) {
        if (sortType == null) {
            sortType = "hot";
        }
        
        switch (sortType) {
            case "latest":
                return Sort.by(Sort.Direction.DESC, "createdAt");
            case "unanswered":
                return Sort.by(Sort.Direction.ASC, "comments")
                          .and(Sort.by(Sort.Direction.DESC, "createdAt"));
            case "hot":
            default:
                // 按热度排序（点赞+评论+收藏），但JPA Sort不支持表达式
                // 这里暂时按点赞数排序，后续可以添加计算字段
                return Sort.by(Sort.Direction.DESC, "likes", "createdAt");
        }
    }

    /**
     * 获取讨论详情
     */
    public DiscussionResponse getDiscussionDetail(Long id, Long currentUserId) {
        // 先从缓存获取
        DiscussionResponse cached = cacheService.getCachedDiscussion(id);
        if (cached != null) {
            // 更新当前用户的点赞/收藏状态（因为每个用户不同）
            if (currentUserId != null) {
                cached.setIsLiked(likeRepository.existsByDiscussionIdAndUserId(id, currentUserId));
                cached.setIsFavorited(favoriteRepository.existsByDiscussionIdAndUserId(id, currentUserId));
            }
            
            // 异步增加浏览量（不影响返回速度）
            incrementViewsAsync(id);
            
            return cached;
        }

        // 缓存未命中，从数据库获取
        Discussion discussion = discussionRepository.findById(id)
                .orElseThrow(() -> new BusinessException("讨论不存在"));

        if (discussion.getIsDeleted() == 1) {
            throw new BusinessException("讨论已被删除");
        }

        // 增加浏览量
        discussion.setViews(discussion.getViews() + 1);
        discussionRepository.save(discussion);

        DiscussionResponse response = toDiscussionResponse(discussion, currentUserId);
        
        // 缓存讨论详情
        cacheService.cacheDiscussion(id, response);

        return response;
    }

    /**
     * 异步增加浏览量
     */
    private void incrementViewsAsync(Long discussionId) {
        new Thread(() -> {
            try {
                Discussion discussion = discussionRepository.findById(discussionId).orElse(null);
                if (discussion != null) {
                    discussion.setViews(discussion.getViews() + 1);
                    discussionRepository.save(discussion);
                }
            } catch (Exception e) {
                // 忽略异常，浏览量统计不是关键功能
            }
        }).start();
    }

    /**
     * 发布讨论
     */
    @Transactional
    public DiscussionResponse createDiscussion(CreateDiscussionRequest request, Long userId) {
        // 创建讨论
        Discussion discussion = new Discussion();
        discussion.setTitle(request.getTitle());
        discussion.setContent(request.getContent());
        discussion.setPreview(generatePreview(request.getContent()));
        discussion.setAuthorId(userId);
        discussion = discussionRepository.save(discussion);

        // 保存标签
        if (request.getTags() != null && !request.getTags().isEmpty()) {
            for (String tagName : request.getTags()) {
                DiscussionTag tag = new DiscussionTag();
                tag.setDiscussionId(discussion.getId());
                tag.setTagName(tagName);
                tagRepository.save(tag);
            }
        }

        DiscussionResponse response = toDiscussionResponse(discussion, userId);
        
        // 缓存新发布的讨论
        cacheService.cacheDiscussion(discussion.getId(), response);
        
        // 清除列表缓存（因为有新内容）
        cacheService.clearDiscussionListCache();

        return response;
    }

    /**
     * 删除讨论
     */
    @Transactional
    public void deleteDiscussion(Long id, Long userId) {
        Discussion discussion = discussionRepository.findById(id)
                .orElseThrow(() -> new BusinessException("讨论不存在"));

        if (!discussion.getAuthorId().equals(userId)) {
            throw new BusinessException("无权限删除");
        }

        discussion.setIsDeleted(1);
        discussionRepository.save(discussion);
        
        // 删除缓存
        cacheService.deleteDiscussionCache(id);
        
        // 清除列表缓存
        cacheService.clearDiscussionListCache();
    }

    /**
     * 点赞/取消点赞讨论
     */
    @Transactional
    public LikeResponse likeDiscussion(Long id, Long userId) {
        Discussion discussion = discussionRepository.findById(id)
                .orElseThrow(() -> new BusinessException("讨论不存在"));

        boolean isLiked;
        if (likeRepository.existsByDiscussionIdAndUserId(id, userId)) {
            // 取消点赞
            likeRepository.deleteByDiscussionIdAndUserId(id, userId);
            discussion.setLikes(Math.max(0, discussion.getLikes() - 1));
            isLiked = false;
        } else {
            // 点赞
            DiscussionLike like = new DiscussionLike();
            like.setDiscussionId(id);
            like.setUserId(userId);
            likeRepository.save(like);
            discussion.setLikes(discussion.getLikes() + 1);
            isLiked = true;
        }

        discussionRepository.save(discussion);
        
        // 更新缓存中的点赞数
        cacheService.updateDiscussionLikes(id, discussion.getLikes(), isLiked);
        
        return new LikeResponse(isLiked, discussion.getLikes());
    }

    /**
     * 收藏/取消收藏讨论
     */
    @Transactional
    public FavoriteResponse favoriteDiscussion(Long id, Long userId) {
        Discussion discussion = discussionRepository.findById(id)
                .orElseThrow(() -> new BusinessException("讨论不存在"));

        boolean isFavorited;
        if (favoriteRepository.existsByDiscussionIdAndUserId(id, userId)) {
            // 取消收藏
            favoriteRepository.deleteByDiscussionIdAndUserId(id, userId);
            discussion.setFavorites(Math.max(0, discussion.getFavorites() - 1));
            isFavorited = false;
        } else {
            // 收藏
            DiscussionFavorite favorite = new DiscussionFavorite();
            favorite.setDiscussionId(id);
            favorite.setUserId(userId);
            favoriteRepository.save(favorite);
            discussion.setFavorites(discussion.getFavorites() + 1);
            isFavorited = true;
        }

        discussionRepository.save(discussion);
        
        // 更新缓存中的收藏数
        cacheService.updateDiscussionFavorites(id, discussion.getFavorites(), isFavorited);
        
        return new FavoriteResponse(isFavorited, discussion.getFavorites());
    }

    /**
     * 获取热门标签
     */
    @SuppressWarnings("unchecked")
    public List<TagResponse> getHotTags() {
        // 先从缓存获取
        Object cached = cacheService.getCachedHotTags();
        if (cached != null) {
            return (List<TagResponse>) cached;
        }

        // 从数据库获取
        List<Map<String, Object>> results = tagRepository.findHotTags();
        
        List<TagResponse> tags = results.stream()
                .limit(20)
                .map(result -> new TagResponse(
                        null,
                        (String) result.get("name"),
                        ((Number) result.get("count")).longValue()
                ))
                .collect(Collectors.toList());
        
        // 缓存热门标签
        cacheService.cacheHotTags(tags);
        
        return tags;
    }

    /**
     * 转换为DiscussionResponse
     */
    private DiscussionResponse toDiscussionResponse(Discussion discussion, Long currentUserId) {
        DiscussionResponse response = new DiscussionResponse();
        response.setId(discussion.getId());
        response.setTitle(discussion.getTitle());
        response.setContent(discussion.getContent());
        response.setPreview(discussion.getPreview());
        response.setLikes(discussion.getLikes());
        response.setComments(discussion.getComments());
        response.setFavorites(discussion.getFavorites());
        response.setCreatedAt(discussion.getCreatedAt());
        response.setUpdatedAt(discussion.getUpdatedAt());

        // 作者信息
        User author = userRepository.findById(discussion.getAuthorId()).orElse(null);
        if (author != null) {
            DiscussionResponse.AuthorInfo authorInfo = new DiscussionResponse.AuthorInfo();
            authorInfo.setId(author.getId());
            authorInfo.setNickname(author.getNickname());
            authorInfo.setAvatar(author.getAvatar());
            authorInfo.setLocation(null); // 可以从用户信息中获取
            response.setAuthor(authorInfo);
        }

        // 标签
        List<String> tags = tagRepository.findByDiscussionId(discussion.getId())
                .stream()
                .map(DiscussionTag::getTagName)
                .collect(Collectors.toList());
        response.setTags(tags);

        // 当前用户是否点赞/收藏
        if (currentUserId != null) {
            response.setIsLiked(likeRepository.existsByDiscussionIdAndUserId(discussion.getId(), currentUserId));
            response.setIsFavorited(favoriteRepository.existsByDiscussionIdAndUserId(discussion.getId(), currentUserId));
        } else {
            response.setIsLiked(false);
            response.setIsFavorited(false);
        }

        return response;
    }

    /**
     * 生成内容预览
     */
    private String generatePreview(String content) {
        // 移除HTML标签
        String text = content.replaceAll("<[^>]*>", "");
        // 截取前200个字符
        if (text.length() > 200) {
            return text.substring(0, 200) + "...";
        }
        return text;
    }
}

